#pragma once
#include <string>
#include <cstddef> // std::size_t
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>// ODB ORM核心功能（对象-关系映射关键）

// ODB编译指令：标记该类为数据库对象，映射到数据库表tbl_student
#pragma db object table("tbl_student")
class Student {
    public:
        Student() {}
        Student(const std::string &name): _name(name) {}
        size_t sn() const { return _sn; }
        void set_sn(size_t sn) { _sn = sn; }
        const std::string &name() const { return _name; }
        void set_name(const std::string &name) { _name = name; }
        odb::nullable<int> age() const { return _age; }
        void set_age(odb::nullable<int> age) { _age = age; }
        odb::nullable<double> score() const { return _score; }
        void set_score(odb::nullable<double> score) { _score = score; }
        odb::nullable<boost::posix_time::ptime> birthday() const { return _birthday; }
        void set_birthday(const boost::posix_time::ptime &birthday) { _birthday = birthday; }
    private:
        friend class odb::access;
        #pragma db id auto
        size_t _sn;
        #pragma db index
        size_t _classes_id;
        std::string _name;
        odb::nullable<int> _age;
        odb::nullable<double> _score;
        odb::nullable<boost::posix_time::ptime> _birthday;
};

// ODB编译指令：标记该类为数据库对象，映射到数据库表tbl_classes
#pragma db object table("tbl_classes")
class Classes {
public:
    Classes() {}
    Classes(const std::string &name): _name(name) {}
    size_t id() const { return _id; }
    void set_id(size_t id) { _id = id; }
    const std::string &name() const { return _name; }
    void set_name(const std::string &name) { _name = name; }
private:
    // 友元声明：允许ODB框架访问私有成员
    friend class odb::access;
    #pragma db id auto
    size_t _id;
    #pragma db unique type("VARCHAR(32)")
    std::string _name;
};

// ODB视图：非数据库实体表，用于存储分组统计结果
// 功能：按班级ID分组，统计每个班级的学生总数和平均分

// 基于Student对象（tbl_student表）创建视图
#pragma db view object(Student) \
    query("group by" + Student::_classes_id + "having " + (?))
// 分组条件：按班级ID分组，having子句预留自定义筛选    
struct GroupCount {
    // ODB指令：映射到Student类的_classes_id字段（即tbl_student.classes_id）
    #pragma db column(Student::_classes_id)
    size_t classes_id;// 班级ID（分组依据）

    // ODB指令：映射到统计函数count(Student._sn)，统计每个班级的学生总数
    #pragma db column("count(" + Student::_sn +")")
    size_t total_stu;// 班级学生总数

    // ODB指令：映射到统计函数avg(Student._score)，别名avg_score，计算班级平均分
    #pragma db column("avg(" + Student::_score + ") as avg_score")
    double avg_score;// 班级学生平均分
};
